14. 推理 Solution

推理

将所有功能组合到一起。最酷的模型测试方法是传入用户生成的数据并且不提供任何真实标签,然后看看结果如何。对于我们的模型来说,传入的数据是一个字符串:你可以编写一条影评,例如 test_review

# negative test review
test_review_neg = 'The worst movie I have seen; acting was terrible and I want my money back. This movie had bad acting and the dialogue was slow.'

可以看出这是一条负面影评,我们看看模型能否正确预测出它的情感。

我们的任务是编写一个 predict 函数,参数包括一个训练过的模型、一条包含普通文本和标点的 test_review,以及进行填充的 sequence_length

根据用户数据做出预测的流程称为推理

预处理 test_review

首先我们需要处理 test_review,将其转换为能够传入模型中的张量。实际上预处理工作量很大,但是这些步骤你都已经见过了。

我拆分成了多个步骤。

我创建了辅助函数 tokenize_review ,它负责处理 test_review 数据。

该函数会接受 test_review,然后执行几项操作:

1.首先将 test_review 转换为小写形式,并删除所有标点,只剩下文字。
2.使用 split() 将文字拆分为单词,获得字词列表。
3.使用 vocab_to_int 字典编码这些字词,我们在这节课开头时已经定义过该字典。

现在我将做出以下假设:该影评是一条影评,不是一批,并且值包含已经存在于字典中的字词,不过你可以添加处理未知字符的代码,我的模型没有这种功能。

from string import punctuation

def tokenize_review(test_review):
    test_review = test_review.lower() # lowercase
    # get rid of punctuation
    test_text = ''.join([c for c in test_review if c not in punctuation])

    # splitting by spaces
    test_words = test_text.split()

    # tokens
    test_ints = []
    test_ints.append([vocab_to_int[word] for word in test_words])

    return test_ints

这个标记化函数将返回一个整数列表,即标记化的影评。

填充并转换为张量

接下来的几个步骤是填充 tokenize_review 函数返回的整数,并变形为 sequence_length;由于模型是用长度为 200 的序列训练而成的,所以我将长度设为 200。使用之前定义的 pad_features 函数填充数据。

最后将填充结果转换为张量。我会将所有这些处理步骤封装到 predict 函数中。

def predict(net, test_review, sequence_length=200):

    net.eval()

    # tokenize review
    test_ints = tokenize_review(test_review)

    # pad tokenized sequence
    seq_length=sequence_length
    features = pad_features(test_ints, seq_length)

    # convert to tensor to pass into your model
    feature_tensor = torch.from_numpy(features)

    batch_size = feature_tensor.size(0)

    # initialize hidden state
    h = net.init_hidden(batch_size)

    if(train_on_gpu):
        feature_tensor = feature_tensor.cuda()

    # get the output from the model
    output, h = net(feature_tensor, h)

    # convert output probabilities to predicted class (0 or 1)
    pred = torch.round(output.squeeze()) 
    # printing output value, before rounding
    print('Prediction value, pre-rounding: {:.6f}'.format(output.item()))

    # print custom response
    if(pred.item()==1):
        print("Positive review detected!")
    else:
        print("Negative review detected.")

使用传入的参数通过辅助函数标记化影评,然后使用填充函数填充影评,并转换为能够传入模型的张量。

然后将张量传入训练过的网络,并返回长度为 1 的输出。通过该输出获得概率最高的类别,舍入后值为 0 或 1,这就是预测结果。

最后,在上述函数的底部针对检测到的正面或负面影评输出自定义消息。

使用正面和负面影评文本测试训练过的模型,看看模型的效果如何。从下面可以看到模型正确地识别出负面测试影评。

识别负面影评

识别负面影评

总结

训练好模型并创建 predict 函数后,我们可以传入任何文本,让模型预测该文本具有正面还是负面情感。看看模型会将哪些字词当做正面字词,将哪些字词当做负面字词。

稍后你将学习如何将这样的模型部署到生产环境中,让模型对用户输入到网络应用中的任何数据做出预测。

你已经实现了很多递归神经网络,太棒啦!